#! /bin/sh

JINX_MAJOR_VER=0.5

HOST_CFLAGS="-O2 -pipe -fstack-clash-protection"
HOST_CXXFLAGS="${HOST_CFLAGS} -Wp,-D_GLIBCXX_ASSERTIONS"
HOST_LDFLAGS="-Wl,-O1 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro -Wl,-z,now"

TARGET_CFLAGS="$HOST_CFLAGS"
TARGET_CXXFLAGS="$HOST_CXXFLAGS"
TARGET_LDFLAGS="$HOST_LDFLAGS"

if [ -z "$ARCHITECTURE" ]; then
    ARCHITECTURE=x86_64
fi

JINX_ARCH=${ARCHITECTURE}

OS_TRIPLET=$ARCHITECTURE-vinix-mlibc

case "$ARCHITECTURE" in
    x86_64)
        TARGET_CFLAGS="$TARGET_CFLAGS -march=x86-64 -mtune=generic -fcf-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer"
        TARGET_CXXFLAGS="$TARGET_CXXFLAGS -march=x86-64 -mtune=generic -fcf-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer"
        TARGET_LDFLAGS="$TARGET_LDFLAGS -Wl,-z,pack-relative-relocs"
        ;;
esac

post_package_strip() {
    if [ -z "$strip_command" ]; then
        strip_command="${OS_TRIPLET}-strip"
    fi

    for f in $(find "${dest_dir}"); do
        if file "$f" | grep 'not stripped' >/dev/null; then
            echo "* stripping '$f'..."
            stripped_file="$(mktemp)"
            ${strip_command} "$f" -o "$stripped_file"
            chmod --reference="$f" "$stripped_file"
            mv -f "$stripped_file" "$f"
        fi
    done
}

autotools_configure() {
        CFLAGS="$TARGET_CFLAGS" \
        CXXFLAGS="$TARGET_CXXFLAGS" \
        LDFLAGS="$TARGET_LDFLAGS" \
    autotools_configure_noflags "$@"
}

autotools_configure_noflags() {
    if [ -z "${configure_script_path}" ]; then
        configure_script_path="${source_dir}/configure"
    fi

        ac_cv_func_malloc_0_nonnull=yes \
        ac_cv_func_calloc_0_nonnull=yes \
        ac_cv_func_realloc_0_nonnull=yes \
    ${configure_script_path} \
        --host=${OS_TRIPLET} \
        --with-sysroot=${sysroot_dir} \
        --prefix=${prefix} \
        --sysconfdir=/etc \
        --localstatedir=/var \
        --bindir=${prefix}/bin \
        --sbindir=${prefix}/bin \
        --libdir=${prefix}/lib \
        --disable-static \
        --enable-shared \
        --disable-malloc0returnsnull \
        "$@"
}

checked_subst() {
    tmpfile="$2".checked_subst
    sed -z -E -e "$1" "$2" >"$tmpfile"
    if cmp -s "$2" "$tmpfile"; then
        rm -f "$2".checked_subst
        if [ "$3" = no_die ]; then
            return 1
        else
            die "*** substitution '$1' failed for file '$2'"
        fi
    fi

    #diff --color=auto -ur "$2" "$tmpfile" || true

    touch -r "$2" "$2".checked_subst
    chmod --reference="$2" "$2".checked_subst
    mv -f "$2".checked_subst "$2"
}

autotools_recursive_regen() {
    for f in $(grep -rl 'GNU config.sub ($timestamp)'); do
        mv "$f" "$f".reference
        cp -v ${base_dir}/build-support/config.sub "$f"
        touch -r "$f".reference "$f"
        rm -f "$f".reference
    done
    for f in $(grep -rl 'GNU config.guess ($timestamp)'); do
        mv "$f" "$f".reference
        cp -v ${base_dir}/build-support/config.guess "$f"
        touch -r "$f".reference "$f"
        rm -f "$f".reference
    done

    if ! [ -z "$(grep -rl "# No shared lib support for Linux oldld, aout, or coff.")" ]; then
        if [ -z "$(grep -rl "dynamic_linker='mlibc ld.so'")" ]; then
            echo "*** Missing libtool support for mlibc - trying to patch support in :3 ***"
            for f in $(grep -rl "We cannot seem to hardcode it, guess we'll fake it."); do
                if grep -q 'add_dir="\?-L$lt_sysroot$libdir"\?' "$f"; then
                    continue
                fi
                checked_subst 's/add_dir=(")?-L\$libdir(")?/add_dir=\1-L$lt_sysroot$libdir\1/g' "$f"
            done
            for f in $(grep -rl "# No shared lib support for Linux oldld, aout, or coff."); do
                if grep -q 'AC_DEFUN(\[AC_PROG_LIBTOOL\]' "$f"; then
                    continue
                fi
                if grep -q 'ltconfig - Create a system-specific libtool' "$f"; then
                    continue
                fi
                checked_subst 's/(# This must be (glibc\/|Linux )?ELF.\nlinux\* \| k\*bsd\*-gnu \| kopensolaris\*-gnu( \| gnu\*)?( \| uclinuxfdpiceabi)?)(\)\n  lt_cv_deplibs_check_method=pass_all)/\1 | *-mlibc\5/g' "$f"
                checked_subst 's/(\)\n	# FreeBSD uses GNU C)/ | *-mlibc\1/g' "$f" no_die || true
                checked_subst 's/(lt_prog_compiler_static(_[^=]*)?='"'"'-non_shared'"'"'\n      ;;)(\n\n    linux\* \| k\*bsd\*-gnu \| kopensolaris\*-gnu( \| gnu\*)?\))/\1\n\n    *-mlibc)\n      lt_prog_compiler_wl\2='"'"'-Wl,'"'"'\n      lt_prog_compiler_pic\2='"'"'-fPIC'"'"'\n      lt_prog_compiler_static\2='"'"'-static'"'"'\n      ;;\3/g' "$f"
                checked_subst 's/(    (haiku|interix\[3-9\])?\*\)\n      (archive_cmds|hardcode_direct)?(_[^=]*)?=)/    *-mlibc)\n      archive_cmds\4='"'"'$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'"'"'\n      archive_expsym_cmds\4='"'"'$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib'"'"'\n      ;;\n\n\1/g' "$f"
                checked_subst 's/(\)\n        # FreeBSD 3 and later use GNU C)/ | *-mlibc\1/g' "$f" no_die || true
                # putting this last to avoid a bug with determining whether the substitutions should be run or not.
                checked_subst 's/(hardcode_into_libs=yes\n  ;;\n\n)(# No shared lib support for Linux oldld, aout, or coff.)/\1*-mlibc)\n  version_type=linux\n  need_lib_prefix=no\n  need_version=no\n  library_names_spec='"'"'$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext'"'"'\n  soname_spec='"'"'$libname$release$shared_ext$major'"'"'\n  dynamic_linker='"'"'mlibc ld.so'"'"'\n  shlibpath_var=LD_LIBRARY_PATH\n  shlibpath_overrides_runpath=no\n  hardcode_into_libs=yes\n  ;;\n\n\2/g' "$f"
            done
        fi
    fi
}

meson_configure() {
        CFLAGS="$TARGET_CFLAGS" \
        CXXFLAGS="$TARGET_CXXFLAGS" \
        LDFLAGS="$TARGET_LDFLAGS" \
    meson_configure_noflags "$@"
}

meson_configure_noflags() {
    if [ -z "${meson_source_dir}" ]; then
        meson_source_dir="${source_dir}"
    fi

    meson setup "${meson_source_dir}" \
        --cross-file "${base_dir}/build-support/cross_file-$ARCHITECTURE.txt" \
        --prefix=${prefix} \
        --sysconfdir=/etc \
        --localstatedir=/var \
        --libdir=lib \
        --sbindir=bin \
        --buildtype=release \
        -Ddefault_library=shared \
        "$@"
}

cmake_configure() {
        CFLAGS="$TARGET_CFLAGS" \
        CXXFLAGS="$TARGET_CXXFLAGS" \
        LDFLAGS="$TARGET_LDFLAGS" \
    cmake_configure_noflags \
        "$@"
}

cmake_configure_noflags() {
    if [ -z "${cmake_source_dir}" ]; then
        cmake_source_dir="${source_dir}"
    fi

    cmake "${cmake_source_dir}" \
        -DCMAKE_MODULE_PATH="${base_dir}/build-support/cmake-host" \
        -DCMAKE_TOOLCHAIN_FILE="${base_dir}/build-support/CMakeToolchain-$ARCHITECTURE.txt" \
        -DCMAKE_INSTALL_PREFIX=${prefix} \
        -DCMAKE_INSTALL_SYSCONFDIR=/etc \
        -DCMAKE_INSTALL_LOCALSTATEDIR=/var \
        -DCMAKE_INSTALL_LIBDIR=lib \
        -DCMAKE_INSTALL_SBINDIR=bin \
        -DCMAKE_BUILD_TYPE=Release \
        -DBUILD_SHARED_LIBS=True \
        -DENABLE_STATIC=False \
        -DPKG_CONFIG_EXECUTABLE="/usr/local/bin/$OS_TRIPLET-pkg-config" \
        -GNinja \
        "$@"
}

if [ "$in_container" = true ]; then
    export VMODULES="/tmp/.vmodules"
    mkdir -p "${VMODULES}"/cache
    mkdir -p /tmp/v_$(id -u)
fi

PROD=true
